/** 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.tompai.datagather.twitter;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
/**
* @desc: datagather-tools
* @name: TwitterSearch.java
* @author: tompai
* @createTime: 2018年5月2日 上午10:43:20
* @history:
* @version: v1.0
*/
public abstract class TwitterSearch {

	public static final Logger LOG = LoggerFactory.getLogger(TwitterSearch.class);
	
	public final static String TYPE_PARAM = "f";
    public final static String QUERY_PARAM = "q";
    public final static String SCROLL_CURSOR_PARAM = "max_position";
    public final static String TWITTER_SEARCH_URL = "https://twitter.com/i/search/timeline";
    
    
    public TwitterSearch() {

    }

    public abstract boolean saveTweets(List<Tweet> tweets);

    //public abstract boolean saveTacounts(final String acount, final String role, List<TweetBean> tweetBeans);
    
    public void search(final String query, final long rateDelay) throws InvalidQueryException {
        TwitterResponse response;
        URL url = constructURL(query, null);
        boolean continueSearch = true;
        String minTweet = null;
        System.out.println(url.toString());
        while((response = executeSearch(url))!=null && continueSearch && !response.getTweets().isEmpty()) {
            if(minTweet==null) {
                minTweet = response.getTweets().get(0).getId();
            }
            continueSearch = saveTweets(response.getTweets());
            String maxTweet = response.getTweets().get(response.getTweets().size()-1).getId();
            if(!minTweet.equals(maxTweet)) {
                try {
                    Thread.sleep(rateDelay);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String maxPosition = "TWEET-" + maxTweet + "-" + minTweet;
                url = constructURL(query, maxPosition);
            } else {
                continueSearch = false;
            }
        }
    }
    
    //use socket5 proxy//
    public static TwitterResponse executeSearch(final URL url) {
    	String content;
        try {
        	content=ShadowSockets5Proxy.twitterLink(url.toString());
        	Gson gson = new Gson();
        	return gson.fromJson(content, TwitterResponse.class);
        } catch(Exception e) {
            // If we get an IOException, sleep for 5 seconds and retry.
            System.err.println("Could not connect to Twitter. Retrying in 5 seconds.");
            try {
                Thread.sleep(5000);
                return executeSearch(url);
            } catch (InterruptedException e2) {
                e.printStackTrace();
            }
        } 
        return null;
    }
    
    //the twitter searche result//
    public static URL constructURL(final String query, final String maxPosition) throws InvalidQueryException {
        if(query==null || query.isEmpty()) {
            throw new InvalidQueryException(query);
        }
        try {
            URIBuilder uriBuilder;
            uriBuilder = new URIBuilder(TWITTER_SEARCH_URL);
            uriBuilder.addParameter(QUERY_PARAM, query);
            uriBuilder.addParameter(TYPE_PARAM, "tweets");
            if (maxPosition != null) {
                uriBuilder.addParameter(SCROLL_CURSOR_PARAM, maxPosition);
            }
            return uriBuilder.build().toURL();
        } catch(MalformedURLException | URISyntaxException e) {
            e.printStackTrace();
            throw new InvalidQueryException(query);
        }
    }
    
}